package com.test.server.handler;

import cn.hutool.core.io.file.FileReader;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.test.constant.FunCodeConstant;
import com.test.constant.HeadCodeConstant;
import com.test.message.*;
import com.test.model.Connection;
import com.test.model.ConnectionManager;
import com.test.server.SyncFuture;
import com.test.server.service.impl.ServerServiceImpl;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

@Slf4j
public class TcpServerHandler extends SimpleChannelInboundHandler<Object> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        ServerServiceImpl serverService = new ServerServiceImpl();
        new Thread(() -> {
            SyncFuture<String> syncFuture = new SyncFuture<>();
            Message message = (Message) msg;
            //消息头码
            short head = message.getHead();

            //功能吗
            byte funCode = message.getFunCode();

            //消息
            byte[] messageData = message.getMessageData();
            log.info("收到消息{}", JSON.toJSONString(message));
            if (FunCodeConstant.LOGIN_CODE == funCode) {
                //1.通讯模块登录0x10
                if (messageData != null && messageData.length > 0 && head == HeadCodeConstant.BB) {
                    LoginRequestMessage loginRequestMessage = JSONObject.parseObject(messageData, LoginRequestMessage.class);
                    //绑定iemi和channel
                    Connection conn = new Connection(ctx.channel(), loginRequestMessage.getImei());
                    if (conn.getChannel().attr(ConnectionManager.connection).get() == null) {
                        log.debug("编号为" + loginRequestMessage.getImei() + "的设备状态为------在线。");
                        conn.register(conn);

                        //收到登录返回消息
                        LoginResponseMessage loginResponseMessage = new LoginResponseMessage();
                        loginResponseMessage.setIemi(loginRequestMessage.getImei());
                        loginResponseMessage.setHeartbeatTime(110);
                        loginResponseMessage.setNoCount(2);
                        loginResponseMessage.setOvertime(10);
                        byte[] bytes = JSON.toJSONBytes(loginResponseMessage);

                        Message responseMsg = new Message();
                        responseMsg.setHead((short) 0xBB);
                        responseMsg.setFunCode((byte) 0x10);
                        responseMsg.setMessageLength((short) bytes.length);
                        responseMsg.setMessageData(bytes);

                        sendSyncMsg(ctx, syncFuture, responseMsg);
                    }
                } else if (head == HeadCodeConstant.BB) {
                    String s = JSON.toJSONString(message);
                    serverService.ackSyncMsg(s, ctx);
                    log.debug("future:{}", message);
                }
            } else if (FunCodeConstant.HEART_BEAT == funCode) {
                //2.通讯模块心跳
                if (messageData != null && messageData.length > 0 && head == HeadCodeConstant.BB) {
                    HeartBeatMessage heartBeatMessage = JSONObject.parseObject(messageData, HeartBeatMessage.class);
                    Connection getConn = ctx.channel().attr(ConnectionManager.connection).get();
                    if (getConn != null) {
                        log.info("收到设备心跳消息{}", heartBeatMessage);

                        //返回消息
                        Message responseMessage = new Message();
                        responseMessage.setHead((short) 0xBB);
                        responseMessage.setFunCode(FunCodeConstant.HEART_BEAT.byteValue());
                        byte[] bytes = new byte[0];
                        responseMessage.setMessageLength((short) bytes.length);
                        responseMessage.setMessageData(bytes);

                        sendSyncMsg(ctx, syncFuture, responseMessage);
                    }
                }

            } else if (FunCodeConstant.GET_UPGRADE_DATA_PACKET == funCode) {
                //4.通讯模块获取升级数据
                if (messageData != null && messageData.length > 0 && head == HeadCodeConstant.BB) {
                    DeviceGetUpdatePackMessage deviceGetUpdatePackMessage = JSONObject.parseObject(messageData, DeviceGetUpdatePackMessage.class);
                    Connection getConn = ctx.channel().attr(ConnectionManager.connection).get();
                    if (getConn != null) {
                        log.info("收到设备升级消息{}", deviceGetUpdatePackMessage);

                        //返回消息
                        Message responseMessage = new Message();
                        responseMessage.setHead((short) 0xBB);
                        responseMessage.setFunCode(FunCodeConstant.HEART_BEAT.byteValue());

                        byte[] bytes = new FileReader("jjj.txt").readBytes();
                        responseMessage.setMessageLength((short) bytes.length);
                        responseMessage.setMessageData(bytes);

                        sendSyncMsg(ctx, syncFuture, responseMessage);
                    }
                }

            } else if (FunCodeConstant.GET_QR_CODE == funCode) {
                //5.获取二维码
                if (head == HeadCodeConstant.BB) {
                    DeviceGetUpdatePackMessage deviceGetUpdatePackMessage = JSONObject.parseObject(messageData, DeviceGetUpdatePackMessage.class);
                    Connection getConn = ctx.channel().attr(ConnectionManager.connection).get();
                    if (getConn != null) {
                        log.info("收到获取二维码消息{}", deviceGetUpdatePackMessage);

                        //返回消息
                        Message responseMessage = new Message();
                        responseMessage.setHead((short) 0xBB);
                        responseMessage.setFunCode(FunCodeConstant.GET_QR_CODE.byteValue());

                        QrCodeMessage qrCodeMessage = new QrCodeMessage();
                        qrCodeMessage.setNumber("000123");
                        byte[] bytes = JSON.toJSONBytes(qrCodeMessage);

                        responseMessage.setMessageLength((short) bytes.length);
                        responseMessage.setMessageData(bytes);

                        sendSyncMsg(ctx, syncFuture, responseMessage);
                    }
                }

            }

//        log.info("SERVER send msg:" + msg);


        }).start();
    }

    private void sendSyncMsg(ChannelHandlerContext ctx, SyncFuture<String> syncFuture, Message message) {
        Connection conn = ctx.channel().attr(ConnectionManager.connection).get();
        ServerServiceImpl.futureCache.put(conn.getImei() + message.getHead() + message.getFunCode(), syncFuture);
        ChannelFuture channelFuture = ctx.channel().writeAndFlush(message);
        //登录回复消息
        log.info("功能：{}收到设备回复消息：{}", message.getFunCode(), message);
        try {
            if (syncFuture.get(8, TimeUnit.SECONDS) != null) {
                channelFuture.addListener((ChannelFutureListener) future -> {
                    if (future.isSuccess()) {
                        log.debug("消息发送成功");
                    } else {
                        log.debug("消息发送失败");
                    }
                });
            } else {
                log.error("服务器接受命令失败");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
